package com.cci.zkweb.core.util;

import java.awt.Color;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;

import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfGState;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;

public class PDFWatermarkText {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		PDFWatermarkText tool = new PDFWatermarkText();
		tool.init();
		String[] params = {"drawText", "dario.durzo@centroitalia.coop.it"};
		tool.createWaterMarkPDF(params, "C:/TEST/test.pdf", "C:/TEST/test2.pdf");
	}

	Hashtable<String, String> defaults = new Hashtable<String, String>();

	public void init() {
		// Initialize defaults.  These are 'commands' that are run before any commands
		// passed in to the extension through the args list
		defaults.put("x", "20");
		defaults.put("y", "20");
		defaults.put("textAngle", "auto");
		defaults.put("textAlign", "L");
		defaults.put("textAlpha", "40");
		defaults.put("textSize", "40");
		defaults.put("textColor", "0xA0A0A0");
	}
	
	public void createWaterMarkPDF(String[] args, String input, String output) {
		try {
			createWaterMarkPDF(args, new FileInputStream(input), new FileOutputStream(output), true);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	public void createWaterMarkPDF(String[] args, InputStream input, OutputStream output, boolean closeOutput) {
		try {
			ArrayList<String[]> actions = new ArrayList<String[]>();

			Enumeration<String> e = defaults.keys();
			while (e.hasMoreElements()) {
				String k = e.nextElement();
				actions.add(new String[] { k, defaults.get(k) });
			}
			for (int i = 0; i < args.length; i += 2) {
				actions.add(new String[] { args[i], args[i + 1] });
			}

			PdfReader reader = new PdfReader(input);

			int n = reader.getNumberOfPages();

			PdfStamper stamp = new PdfStamper(reader, output);
			/*
			stamp.setEncryption(
					PdfWriter.STANDARD_ENCRYPTION_128 | PdfWriter.DO_NOT_ENCRYPT_METADATA, 
					null, null,
					PdfWriter.ALLOW_PRINTING | PdfWriter.ALLOW_COPY
					| PdfWriter.ALLOW_FILL_IN | PdfWriter.ALLOW_SCREENREADERS
					| PdfWriter.ALLOW_DEGRADED_PRINTING);
			*/
			for (int i = 1; i <= n; i++) {
				PdfContentByte pageContent = stamp.getOverContent(i);
				Rectangle pageSize = reader.getPageSizeWithRotation(i);

				watermarkPage(pageContent, actions, pageSize.getWidth(), pageSize.getHeight());
			}

			stamp.close();
			input.close();
			input = null;
			if(closeOutput) {
				output.close();
				output = null;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void watermarkPage(PdfContentByte pageContent, ArrayList<String[]> actions, float width, float height)
	throws Exception {
		float x = 0;
		float y = 0;
		double textAngle = 0;
		int textAlign = PdfContentByte.ALIGN_CENTER;
		int fontSize = 14;

		pageContent.beginText();

		for (int i = 0; i < actions.size(); i++) {
			String action = actions.get(i)[0];
			String value = actions.get(i)[1];

			if (action.equals("x")) {
				x = Float.parseFloat(value) / 100 * width;
				continue;
			}

			if (action.equals("y")) {
				y = Float.parseFloat(value) / 100 * height;
				continue;
			}

			if (action.equals("textColor")) {
				pageContent.setColorFill(Color.decode(value));
				pageContent.setColorStroke(Color.decode(value));
				continue;
			}

			if (action.equals("textAlpha")) {
				PdfGState gs1 = new PdfGState();
				gs1.setFillOpacity(Float.parseFloat(value) / 100f);
				gs1.setStrokeOpacity((Float.parseFloat(value)) / 200f);
				pageContent.setGState(gs1);
				continue;
			}

			if (action.equals("textAngle")) {
				if (value.equals("auto")) {
					textAngle = (float) Math.atan2(height, width);
				} else {
					textAngle = Math.toRadians( Double.parseDouble(value) );
				}
				continue;
			}

			if (action.equals("textAlign")) {
				if (value.equals("L")) {
					textAlign = PdfContentByte.ALIGN_LEFT;
				} else if (value.equals("R")) {
					textAlign = PdfContentByte.ALIGN_RIGHT;
				} else {
					textAlign = PdfContentByte.ALIGN_CENTER;
				}
				continue;
			}

			if (action.equals("textSize")) {
				fontSize = Integer.parseInt(value);
				pageContent.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL); 
				pageContent.setFontAndSize(BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED), fontSize);
				continue;
			}

			// x,y is top left/center/right of text, so that when we move the
			// cursor at the end of a line, we can cater for subsequent fontSize 
			// changes
			if (action.equals("drawText")) {
				pageContent.showTextAligned(textAlign, value,
						(float) (x + fontSize * Math.sin(textAngle)),
						(float) (y - fontSize * Math.cos(textAngle)),
						(float) Math.toDegrees(textAngle));

				x += fontSize * 1.2 * Math.sin(textAngle);
				y -= fontSize * 1.2 * Math.cos(textAngle);
				continue;
			}

			throw new Exception("Unknown command '" + action + "'");
		}

		pageContent.endText();
	}
}